package com.lihaozhe.orderservice.service;

import com.lihaozhe.orderservice.client.PaymentServiceClient;
import com.lihaozhe.orderservice.client.ProductServiceClient;
import com.lihaozhe.orderservice.client.UserServiceClient;
import com.lihaozhe.orderservice.dto.OrderDTO;
import com.lihaozhe.orderservice.dto.OrderItemDTO;
import com.lihaozhe.productservice.dto.ProductDTO;
import com.lihaozhe.userservice.dto.UserDTO;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 订单服务类 - Feign版本
 * 使用Feign客户端调用其他微服务，代码更简洁
 *
 * @author 李昊哲
 * @version 1.0.0
 */
@Service
public class OrderService {

  private final UserServiceClient userServiceClient;
  private final ProductServiceClient productServiceClient;
  private final PaymentServiceClient paymentServiceClient;

  private final List<OrderDTO> orders = new ArrayList<>();
  private Long orderIdCounter = 1L;

  /**
   * 构造函数，注入Feign客户端
   */
  public OrderService(UserServiceClient userServiceClient,
                      ProductServiceClient productServiceClient,
                      PaymentServiceClient paymentServiceClient) {
    this.userServiceClient = userServiceClient;
    this.productServiceClient = productServiceClient;
    this.paymentServiceClient = paymentServiceClient;
  }

  /**
   * 创建订单 - 使用Feign调用其他服务
   *
   * @param orderRequest 订单请求
   * @return 订单创建结果
   */
  public Map<String, Object> createOrder(Map<String, Object> orderRequest) {
    Long userId = Long.valueOf(orderRequest.get("userId").toString());
    Long productId = Long.valueOf(orderRequest.get("productId").toString());
    Integer quantity = Integer.valueOf(orderRequest.get("quantity").toString());

    System.out.println("使用Feign创建订单 - 用户ID: " + userId + ", 商品ID: " + productId);

    try {
      // 1. 使用Feign调用用户服务 - 像调用本地方法一样简单
      UserDTO user = userServiceClient.getUserById(userId);
      if (user == null) {
        return Map.of("success", false, "message", "用户不存在");
      }

      // 2. 使用Feign调用商品服务
      Map<String, Object> productResponse = productServiceClient.getProductById(productId);
      if (productResponse == null || productResponse.get("product") == null) {
        return Map.of("success", false, "message", "商品不存在");
      }

      // 3. 提取商品信息
      Map<String, Object> productMap = (Map<String, Object>) productResponse.get("product");
      ProductDTO product = mapToProductDTO(productMap);

      // 4. 检查库存
      if (product.getStock() < quantity) {
        return Map.of("success", false, "message", "库存不足");
      }

      // 5. 创建订单
      OrderItemDTO orderItem = new OrderItemDTO(productId, product.getName(), quantity, product.getPrice());
      List<OrderItemDTO> items = List.of(orderItem);
      Double totalAmount = product.getPrice() * quantity;

      OrderDTO order = new OrderDTO(orderIdCounter++, userId, items, totalAmount, "CREATED");
      orders.add(order);

      // 6. 更新库存
      Map<String, Integer> stockUpdate = Map.of("quantity", -quantity);
      productServiceClient.updateStock(productId, stockUpdate);

      // 7. 调用支付服务
      Map<String, Object> paymentResult = processPayment(order, user);

      // 8. 更新订单状态
      if (Boolean.TRUE.equals(paymentResult.get("success"))) {
        order.setStatus("PAID");
      } else {
        order.setStatus("PAYMENT_FAILED");
      }

      return Map.of(
          "success", true,
          "message", "订单创建成功",
          "orderId", order.getId(),
          "totalAmount", totalAmount,
          "user", user.getUsername(),
          "product", product.getName(),
          "payment", paymentResult,
          "instanceInfo", productResponse.get("instanceInfo")
      );

    } catch (Exception e) {
      System.err.println("创建订单失败: " + e.getMessage());
      return Map.of("success", false, "message", "创建订单失败: " + e.getMessage());
    }
  }

  /**
   * 处理支付 - 使用Feign调用支付服务
   */
  private Map<String, Object> processPayment(OrderDTO order, UserDTO user) {
    Map<String, Object> paymentRequest = Map.of(
        "orderId", order.getId(),
        "amount", order.getTotalAmount(),
        "userId", user.getId(),
        "userName", user.getUsername(),
        "paymentMethod", "ALIPAY"  // 模拟支付方式
    );

    // 使用Feign调用支付服务
    return paymentServiceClient.createPayment(paymentRequest);
  }

  /**
   * 获取订单详情
   */
  public OrderDTO getOrder(Long orderId) {
    return orders.stream()
        .filter(o -> o.getId().equals(orderId))
        .findFirst()
        .orElse(null);
  }

  /**
   * 获取用户订单列表
   */
  public List<OrderDTO> getUserOrders(Long userId) {
    // 验证用户是否存在
    try {
      UserDTO user = userServiceClient.getUserById(userId);
      if (user == null) {
        return List.of();
      }
    } catch (Exception e) {
      System.err.println("验证用户失败: " + e.getMessage());
      return List.of();
    }

    return orders.stream()
        .filter(o -> o.getUserId().equals(userId))
        .toList();
  }

  /**
   * 获取所有用户信息 - 演示Feign调用返回列表
   */
  public List<UserDTO> getAllUsers() {
    try {
      return userServiceClient.getAllUsers();
    } catch (Exception e) {
      System.err.println("获取用户列表失败: " + e.getMessage());
      return List.of();
    }
  }

  /**
   * 根据分类获取商品 - 演示带路径参数的Feign调用
   */
  public Map<String, Object> getProductsByCategory(String category) {
    try {
      return productServiceClient.getProductsByCategory(category);
    } catch (Exception e) {
      System.err.println("根据分类获取商品失败: " + e.getMessage());
      return Map.of("products", List.of(), "error", e.getMessage());
    }
  }

  /**
   * 测试Feign负载均衡 - 连续调用观察实例分布
   */
  public Map<String, Object> testFeignLoadBalancing(int callCount) {
    Map<String, Integer> distribution = new java.util.HashMap<>();

    for (int i = 0; i < callCount; i++) {
      try {
        Map<String, Object> instanceInfo = productServiceClient.getInstanceInfo();
        if (instanceInfo != null) {
          String instanceId = (String) instanceInfo.get("instanceId");
          distribution.put(instanceId, distribution.getOrDefault(instanceId, 0) + 1);
        }

        // 短暂延迟
        Thread.sleep(10);
      } catch (Exception e) {
        System.err.println("Feign负载均衡测试调用失败: " + e.getMessage());
      }
    }

    return Map.of(
        "totalCalls", callCount,
        "distribution", distribution,
        "method", "Feign客户端"
    );
  }

  /**
   * 将Map转换为ProductDTO
   */
  private ProductDTO mapToProductDTO(Map<String, Object> productMap) {
    ProductDTO product = new ProductDTO();
    product.setId(Long.valueOf(productMap.get("id").toString()));
    product.setName((String) productMap.get("name"));
    product.setCategory((String) productMap.get("category"));
    product.setPrice(Double.valueOf(productMap.get("price").toString()));
    product.setStock(Integer.valueOf(productMap.get("stock").toString()));
    product.setDescription((String) productMap.get("description"));
    return product;
  }
}
